import {
	CITY_ID,
	isH5,
	EARLY_LOCATION_KEY
} from '@/constant/index.js'
import {
	toast
} from '@/utils/tool.js'
import request from '@/utils/request.js'


function getLocationCache() {
	const value = {
		location: {
			lat: 0,
			lng: 0
		},
		city: '',
		cityId: '',
	}
	const result = uni.getStorageSync(CITY_ID)
	if (!result) return value
	if (typeof result !== 'object') return result
	for (let key in result) {
		value[key] = result[key]
	}
	return value
}

export default {
	namespaced: true,
	state: () => {
		const {
			cityId,
			location,
			city
		} = getLocationCache()
		return {
			shouldUpdate: false,
			hasInit: false,
			cityId,
			appKey: '6BLBZ-CDWL3-77X3R-R43DI-ISSV5-SNBWU',
			requestUrl: 'https://apis.map.qq.com',
			location,
			city,
			cityCode: {},
			recentlyData: uni.getStorageSync(EARLY_LOCATION_KEY) || [],
			addressText: uni.getStorageSync('address_text') || '-',
		}
	},
	actions: {
		getCityDataByLocation(_, cityCode) {
			return new Promise(async resolve => {
				const resp = await request({
					url: "/index/getCity",
					data: {
						code: cityCode
					},
					method: 'GET',
				})
				const {
					code,
					data,
					msg
				} = resp
				if (code !== 1) {
					resolve([data, null])
					return toast({
						title: msg
					})
				}
				resolve([null, data])
			})
		},
		getCityId({
			commit,
			dispatch,
			rootState
		}, [codeValue, type]) {
			return new Promise(async resolve => {
				const [error, data] = await dispatch('getCityDataByLocation', codeValue)
				if (error) return resolve([error, null])
				const {
					name,
					id
				} = data
				if (type) return resolve([null, data])
				commit('setCityCode', data)
				commit('setCityId', id)
				commit('setCity', name)
				commit('updateCache')
				rootState.hasLocation = true
				resolve([null, id])
			})
		},
		getLocation() {
			return new Promise(resolve => {
				if (isH5) {
					return resolve([null, {
						lat: 30.235535,
						lng: 120.113681
					}])
				}
				uni.getLocation({
					success: resp => {
						const {
							longitude,
							latitude
						} = resp
						resolve([null, {
							lng: longitude,
							lat: latitude
						}])
					},
					fail: err => {
						resolve([err, null])
					}
				})
			})
		},
		getLngLatByAddress({
			state
		}, address) {
			return new Promise(resolve => {
				const {
					appKey,
					requestUrl
				} = state
				const url =
					`${isH5 ? '/location' : requestUrl}/ws/geocoder/v1/?address=${address}&key=${appKey}`
				uni.request({
					url,
					method: 'GET',
					success: response => {
						const {
							statusCode,
							data
						} = response
						if (statusCode !== 200) {
							return resolve([data, null])
						}
						resolve([null, data.result])
					},
					fail: err => {
						resolve([err, null])
					}
				})
			})
		},
		getLocationInfoByQQ({
			state
		}, {
			lng,
			lat
		}) {
			return new Promise(resolve => {
				const {
					appKey,
					requestUrl
				} = state
				const url =
					`${isH5 ? '/location' : requestUrl}/ws/geocoder/v1/?location=${lat},${lng}&key=${appKey}&get_poi=1`
				uni.request({
					url,
					method: 'GET',
					success: response => {
						const {
							statusCode,
							data
						} = response
						if (statusCode !== 200) {
							return resolve([data, null])
						}
						resolve([null, data.result])
					},
					fail: err => {
						resolve([err, null])
					}
				})
			})
		},
		getAddressByLocation({
			dispatch
		}, {
			lng,
			lat
		}) {
			return new Promise(async resolve => {
				const [locationError, result] = await dispatch('getLocationInfoByQQ', {
					lng,
					lat
				})
				if (locationError) return resolve([locationError, null])
				const {
					ad_info: {
						phone_area_code
					}
				} = result
				const [error, cityData] = await dispatch('getCityDataByLocation', phone_area_code)
				if (error) return resolve([error, null])
				resolve([null, cityData])
			})
		},
		getAddress({
			dispatch,
			commit
		}, payloadData) {
			return new Promise(async resolve => {
				let lng = 0,
					lat = 0;
				let reqType = false
				if (!payloadData) {
					const [error, resp] = await dispatch('getLocation')
					if (error) {
						resolve([error, null])
						console.log(error, 'error');
						return toast({
							title: '获取位置信息失败'
						})
					}
					lng = resp.lng
					lat = resp.lat
				} else {
					lat = payloadData.lat
					lng = payloadData.lng
					if (payloadData.type) reqType = true
				}
				const [locationErr, locationResp] = await dispatch('getLocationInfoByQQ', {
					lng,
					lat
				})
				if (locationErr) return resolve([locationErr, null])
				const {
					location,
					ad_info: {
						phone_area_code
					}
				} = locationResp
				if (!reqType) commit('setLocation', location)
				const codeResp = await dispatch('getCityId', [phone_area_code, reqType])
				codeResp.push(locationResp)
				const {
					city,
					district,
					province,
				} = locationResp.address_component
				commit('setAddressText', `${province}-${city}-${district}`)
				resolve(codeResp)
			})
		},
	},
	mutations: {
		setAddressText(state, v) {
			state.addressText = v
			uni.setStorageSync('address_text', v)
		},
		addRecentlyData(state, value) {
			const {
				id
			} = value
			const {
				recentlyData
			} = state
			const index = recentlyData.findIndex(item => item.id === id)
			if (index < 0) {
				if (recentlyData.length >= 3) recentlyData.splice(2)
				state.recentlyData.unshift(value)
				return uni.setStorage({
					key: EARLY_LOCATION_KEY,
					data: state.recentlyData
				})
			}
			state.recentlyData.splice(index, 1)
			state.recentlyData.unshift(value)
			uni.setStorage({
				key: EARLY_LOCATION_KEY,
				data: state.recentlyData
			})
		},
		setUpdate(state, value) {
			state.shouldUpdate = value
		},
		setCityId(state, id) {
			state.cityId = id
			state.hasInit = true
		},
		setCityCode(state, value) {
			state.cityCode = value
		},
		updateCache(state) {
			const {
				cityId,
				location,
				city
			} = state
			uni.setStorage({
				key: CITY_ID,
				data: {
					cityId,
					location,
					city
				}
			})
		},
		setCity(state, value) {
			state.city = value
		},
		setLocation(state, value) {
			state.location = value
		}
	},
}